
#include <librally.h>
#include <rindex.h>
#include "adm.h"
#include ""				// TODO: header files

static rp_thread_t tid_sched;
static rp_thread_t tid_dispatch;

//* Function: rp_rindexd_server_init()
//*  	To initialize a rindexd server
//*
void rp_rindexd_server_init()
{
	char fname[] = "rp_rindexd_server_init";
	char msg[] = "fatal error";
	Err err;
	
	err = rp_rindexd_getopt(argc, argv);
	err = rp_daemonize();
	rp_rindexd_env_init();
	rp_rindexd_config_init();	
	rp_rindexd_global_init();
	rp_rindexd_log_init();
	FLOG_IN(fname);

	/* 	socket init    */
	if (rp_comm_tcp_server_init(&(global.fd_rstatd), &(config.addr_rstatd), COMM_NONBLOCK) != E_OK)
	{
		rp_log(LOG_FATAL, fname, "Cannot start Manager server with IP address: %s; Port: %d."); 	// TODO:
		exit(127);
	}
	if (rp_comm_tcp_server_init(&(global.fd_adm), &(config.addr_adm), COMM_NONBLOCK) != E_OK)
	{
		rp_log(LOG_FATAL, fname, "Cannot start Command server with IP address: %s; Port: %d."); 	// TODO:
		exit(127);
	}
	if (rp_comm_tcp_server_init(&(global.fd_client), &(config.addr_client), COMM_NONBLOCK) != E_OK)
	{
		rp_log(LOG_FATAL, fname, "Cannot start Listener server with IP address: %s; Port: %d.");		// TODO:
		exit(127);
	}
	
	/*	event init	    */
	event_init();
	event_set(&global.ev_rstatd, global.fd_rstatd, EV_READ|EV_PERSIST, rp_rindexd_heartbeat, NULL);  
	if (event_add(&global.ev_rstatd, NULL) < 0)		// to recv heartbeat info from data host's rstatd
	{
		rp_log(LOG_FATAL, fname, "Add heartbeat event failed.");
		exit(127);
	}
	event_set(&global.ev_cmd, global.fd_cmd, EV_READ|EV_PERSIST, rp_rindexd_adm, NULL);  
	if (event_add(&global.ev_cmd, NULL) < 0)    	// to recv cmd from CLI or GUI
	{
		rp_log(LOG_FATAL, fname, "Add command event failed.");
		exit(127);
	}
	event_set(&global.ev_listener, global.fd_listener, EV_READ|EV_PERSIST, rp_rindexd_listener, NULL);  
	if (event_add(&global.ev_listener, NULL) < 0)	// to listen to client requests
	{
		rp_log(LOG_FATAL, fname, "Add listener event failed.");
		exit(127);
	}
	
	/* 	create threads	   */
	err = rp_thread_create(&(global.tid_manager), rp_rindexd_manager, NULL);
	
	int i;
	Status *status;
	for (i=0; i<config.num_thread_prestart; i++)
	{
		status = global.status_sched+i;
		err = rp_thread_create(&(status->tid), rp_rindexd_scheduler, NULL);
	}

	/*	create B*Tree    */
	err = rp_tree_init();

	
	return;
}

void rp_rindexd_server_run()
{
	char fname[] = "rp_rindexd_server_run";
	char msg[] = "fatal error";
	Err err;
	FLOG_IN(fname);

	event_dispatch();

	FLOG_OUT(fname);
	return;
}

void rp_rindexd_server_finalize()
{

}

int main(int argc, char* argv[])
{
	rp_rindexd_server_init();
 	rp_rindexd_server_run();	// start the rindexd server
 	rp_rindexd_server_finalize();

	return 0;
}

